package org.ne.springboot.interceptor;

import io.minio.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.ne.springboot.pojo.MinioPojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author wey
 * @date 2025/7/25 下午8:56 07
 **/


@Component
public class MinioService {
    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioPojo minioProperties;

    /*
     * 上传文件
     * */
    public String uploadFile(MultipartFile file) {
        try {
//判断桶是否存在

//            String policyJson = "{\"Statement\"[{\"Action[\"s3:GetObject\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Resource\":[\"arn:aws:s3:::" + minioProperties.getBucketName() + "/*\"],\"Sid\":\"\"}],\"Version\":\"2012-10-17\"}";
//            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(minioProperties.getBucketName()).config(policyJson).build());
            boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProperties.getBucketName()).build());
            if (!bucketExists){
//                如果不存在，就创建桶
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioProperties.getBucketName()).build());
            }
//            本地时间，具体到年、月、日
            String yyyymmdd = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//            String uuid= UUID.randomUUID().toString();
            String filename = yyyymmdd+"/"+file.getOriginalFilename();
//          加一个/表示创建一个文件夹
            minioClient.putObject(PutObjectArgs.builder().
                    bucket(minioProperties.getBucketName()).
                    object(filename).
                    stream(file.getInputStream(), file.getSize(), -1).
//                    文件上传的类型，如果不指定，那么每次访问时都要先下载文件
        contentType(file.getContentType()).
                    build());
            String url= minioProperties.getUrl()+"/"+ minioProperties.getBucketName()+"/"+filename;
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("文件上传失败");
        }
    }




    /*
     * 根据url 下载文件
     * */
    /*public String getObject(HttpServletRequest request, HttpServletResponse response, String url){
//        将传递的url 进行切割，获取到相对于桶的文件名
        String objectUrl = url.split(minioProperties.getBucketName()+"/")[1];
//        文件名
        String fileName = objectUrl.split("/")[1];
        // 设置响应的内容类型为文件类型
        response.setContentType("application/octet-stream");
//        application/msword
        // 设置响应头，指定文件名
        response.setHeader("Content-Disposition", "attachment; filename=\"filename.extension\"");
        // 缓冲区大小
        byte[] buffer = new byte[1024];
        int bytesRead;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try{
            inputStream = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .object(objectUrl)
                    .build());
            // 将输入流的内容复制到一个文件中
            String filePath = "C://"+fileName;
            Files.copy(inputStream, Path.of(filePath),
                    StandardCopyOption.REPLACE_EXISTING);
            // 获取输出流
            outputStream = response.getOutputStream();
            // 将输入流中的数据写入输出流
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            inputStream.close();
            outputStream.close();
            return "文件下载成功，地址为"+filePath;
        }catch (Exception e){
            e.printStackTrace();
        }
        return "文件下载失败";
    }*/
    public void getObject(HttpServletResponse response, String url) {
        try {
            // 解析对象路径（需防范路径遍历攻击）
            String objectUrl = url.split(minioProperties.getBucketName() + "/")[1];
            // 安全提取文件名
            String fileName = objectUrl.substring(objectUrl.lastIndexOf("/") + 1);

            // 设置响应头：强制下载 + 动态文件名
            // 通用二进制流
            response.setContentType("application/msword");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + "\"");

            // 直接从 MinIO 获取流并写入响应
            try (InputStream inputStream = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .object(objectUrl)
                    .build());
                 OutputStream outputStream = response.getOutputStream()) {

                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
            }
        } catch (Exception e) {
//            e.printStackTrace();
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    public void deleteFile(String url) {
        //        将传递的url 进行切割，获取到相对于桶的文件名
        String objectUrl = url.split(minioProperties.getBucketName()+"/")[1];
        try {

            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .object(objectUrl)
                    .build());

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(url+"文件删除失败");
        }
    }


}
